package org.mili.ticketeer.dao;

import org.mili.application.dao.AbstractDao;
import org.mili.application.dao.DaoException;
import org.mili.application.dao.ModificationResult;
import org.mili.application.dao.RowTransformer;
import org.mili.application.dao.query.QueryBuilder;
import org.mili.ticketeer.dto.Group;
import org.mili.application.dto.Identifieable;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GroupDao extends AbstractDao {

    private Map<String, Group> cache = new HashMap<>();
    private Map<Integer, Group> idCache = new HashMap<>();

    public GroupDao() {
        super(Group.Fields.values(), Group.Fields.values(), Group.TABLE);
    }

    public List<Group> getGroups() throws DaoException {
        return read(new GroupRowTransformer());
    }

    public ModificationResult write(final Group group) throws DaoException {
        cache.clear();
        idCache.clear();
        return createOrUpdate(group);
    }

    public Group findById(final int id) throws DaoException {
        Group group = idCache.get(id);
        if (group == null) {
            group = (Group) readSingle(
                    new GroupRowTransformer(),
                    QueryBuilder.createQueryBuilder()
                            .select()
                            .fields(Identifieable.Fields.ID, fields)
                            .from(table)
                            .where()
                            .eq(Identifieable.Fields.ID, id).build());
            idCache.put(id, group);
        }
        return group;
    }

    public Group findByName(final String name) throws DaoException {
        Group group = cache.get(name);
        if (group == null) {
            group = (Group) readSingle(
                    new GroupRowTransformer(),
                    QueryBuilder.createQueryBuilder()
                            .select()
                            .fields(Identifieable.Fields.ID, fields)
                            .from(table)
                            .where()
                            .eq(Group.Fields.NAME, name).build());
            cache.put(name, group);
        }
        return group;
    }

    static class GroupRowTransformer implements RowTransformer<Group> {
        @Override
        public Group transform(ResultSet resultSet) throws SQLException {
            Group group = new Group();
            group.setId(resultSet.getInt(Identifieable.Fields.ID.name()));
            group.setName(resultSet.getString(Group.Fields.NAME.name()));
            return group;
        }
    }

}
